package com.ygswglxt.leave.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.ygswglxt.leave.entity.LeaveRecord;
import com.ygswglxt.leave.mapper.LeaveMapper;
import com.ygswglxt.leave.service.LeaveBalanceService;
import com.ygswglxt.common.Result;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;

import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.ArrayList;

@Service
public class LeaveService {
    
    @Autowired
    private LeaveMapper leaveMapper;
    
    @Autowired
    private LeaveBalanceService leaveBalanceService;
    
    @Autowired(required = false)
    private RocketMQTemplate rocketMQTemplate;
    
    private RestTemplate restTemplate = new RestTemplate();
    private static final String NOTIFICATION_SERVICE_URL = "http://localhost:8086/notification/create";
    private static final String USER_SERVICE_URL = "http://localhost:8082/user/managers";
    
    // 查询所有经理ID（用于发送审批通知）
    private List<Long> getManagerIds() {
        try {
            Result result = restTemplate.getForObject(USER_SERVICE_URL, Result.class);
            if (result != null && result.getCode() != null && result.getCode().equals(200)) {
                List<Map<String, Object>> managers = (List<Map<String, Object>>) result.getData();
                List<Long> managerIds = new ArrayList<>();
                for (Map<String, Object> manager : managers) {
                    Long id = ((Number) manager.get("id")).longValue();
                    managerIds.add(id);
                }
                return managerIds;
            }
        } catch (Exception e) {
            System.err.println("查询经理列表失败: " + e.getMessage());
        }
        return new ArrayList<>();
    }
    
    // 备用方案：直接通过HTTP调用通知服务
    private void createNotificationDirectly(Long userId, String type, String title, String content, Long relatedId, String relatedType) {
        try {
            Map<String, Object> params = new HashMap<>();
            params.put("userId", userId);
            params.put("type", type);
            params.put("title", title);
            params.put("content", content);
            if (relatedId != null) {
                params.put("relatedId", relatedId);
            }
            if (relatedType != null) {
                params.put("relatedType", relatedType);
            }
            
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            HttpEntity<String> request = new HttpEntity<>(com.alibaba.fastjson.JSON.toJSONString(params), headers);
            
            restTemplate.postForObject(NOTIFICATION_SERVICE_URL, request, Result.class);
            System.out.println("✓ 通过HTTP直接创建通知成功 - userId: " + userId + ", type: " + type);
        } catch (Exception e) {
            System.err.println("❌ HTTP直接创建通知失败: " + e.getMessage());
            e.printStackTrace();
        }
    }
    
    public Result<String> applyLeave(LeaveRecord leaveRecord) {
        // 确保日期格式正确
        if (leaveRecord.getStartDate() == null || leaveRecord.getEndDate() == null) {
            return Result.error("请选择开始和结束日期");
        }
        
        // 计算天数
        if (leaveRecord.getDays() == null || leaveRecord.getDays() <= 0) {
            long diff = leaveRecord.getEndDate().getTime() - leaveRecord.getStartDate().getTime();
            int days = (int) (diff / (1000 * 60 * 60 * 24)) + 1;
            leaveRecord.setDays(days);
        }
        
        leaveRecord.setStatus("PENDING");
        leaveRecord.setCreateTime(new Date());
        leaveMapper.insert(leaveRecord);
        
        // 发送MQ消息通知（如果RocketMQ可用）
        boolean mqSuccess = false;
        if (rocketMQTemplate != null) {
            try {
                Map<String, Object> message = new HashMap<>();
                message.put("userId", leaveRecord.getUserId());
                message.put("type", "LEAVE_APPLY");
                message.put("leaveId", leaveRecord.getId());
                message.put("leaveType", leaveRecord.getType());
                message.put("days", leaveRecord.getDays());
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                if (leaveRecord.getStartDate() != null) {
                    message.put("startDate", sdf.format(leaveRecord.getStartDate()));
                }
                if (leaveRecord.getEndDate() != null) {
                    message.put("endDate", sdf.format(leaveRecord.getEndDate()));
                }
                rocketMQTemplate.convertAndSend("leave-topic", com.alibaba.fastjson.JSON.toJSONString(message));
                mqSuccess = true;
            } catch (Exception e) {
                // MQ发送失败，使用备用方案
                System.err.println("MQ消息发送失败，使用HTTP备用方案: " + e.getMessage());
            }
        }
        
        // 如果MQ发送失败，使用HTTP直接调用通知服务（备用方案）
        if (!mqSuccess) {
            String typeName = "";
            if ("ANNUAL".equals(leaveRecord.getType())) {
                typeName = "年假";
            } else if ("SICK".equals(leaveRecord.getType())) {
                typeName = "病假";
            } else if ("PERSONAL".equals(leaveRecord.getType())) {
                typeName = "事假";
            } else if ("ADJUSTMENT".equals(leaveRecord.getType())) {
                typeName = "调休";
            }
            // 查询所有经理，给每个经理发送通知
            List<Long> managerIds = getManagerIds();
            if (managerIds.isEmpty()) {
                // 如果没有找到经理，记录警告但不影响主流程
                System.err.println("⚠️ 未找到经理，无法发送审批通知");
            } else {
                // 给每个经理发送通知
                for (Long managerId : managerIds) {
                    createNotificationDirectly(
                        managerId,
                        "APPROVAL_PENDING",
                        "待审批：请假申请",
                        "您有新的" + typeName + "申请需要审批，天数：" + leaveRecord.getDays() + "天",
                        leaveRecord.getId(),
                        "LEAVE"
                    );
                }
            }
        }
        
        return Result.success("请假申请已提交");
    }
    
    @Transactional
    public Result<String> approveLeave(Long leaveId, Long approverId, String status) {
        LeaveRecord record = leaveMapper.selectById(leaveId);
        if (record == null) {
            return Result.error("请假记录不存在");
        }
        
        UpdateWrapper<LeaveRecord> wrapper = new UpdateWrapper<>();
        wrapper.eq("id", leaveId);
        wrapper.set("status", status);
        wrapper.set("approver_id", approverId);
        leaveMapper.update(null, wrapper);
        
        // 如果审批通过，扣除相应的假期余额
        if ("APPROVED".equals(status)) {
            BigDecimal days = BigDecimal.valueOf(record.getDays() != null ? record.getDays() : 0);
            Result<String> deductResult = leaveBalanceService.deductBalance(
                record.getUserId(),
                record.getType(),
                days,
                leaveId,
                "请假审批通过，自动扣除"
            );
            if (deductResult.getCode() == null || !deductResult.getCode().equals(200)) {
                // 如果扣除失败，回滚审批状态
                wrapper.set("status", "PENDING");
                leaveMapper.update(null, wrapper);
                return Result.error("审批失败：" + deductResult.getMessage());
            }
        }
        
        // 发送MQ消息通知审批结果（如果RocketMQ可用）
        boolean mqSuccess = false;
        if (rocketMQTemplate != null) {
            try {
                Map<String, Object> message = new HashMap<>();
                message.put("userId", record.getUserId());
                message.put("type", "LEAVE_APPROVE");
                message.put("leaveId", leaveId);
                message.put("status", status);
                message.put("approverId", approverId);
                message.put("leaveType", record.getType());
                message.put("days", record.getDays());
                rocketMQTemplate.convertAndSend("leave-topic", com.alibaba.fastjson.JSON.toJSONString(message));
                mqSuccess = true;
            } catch (Exception e) {
                // MQ发送失败，使用备用方案
                System.err.println("MQ消息发送失败，使用HTTP备用方案: " + e.getMessage());
            }
        }
        
        // 如果MQ发送失败，使用HTTP直接调用通知服务（备用方案）
        if (!mqSuccess) {
            String typeName = "";
            if ("ANNUAL".equals(record.getType())) {
                typeName = "年假";
            } else if ("SICK".equals(record.getType())) {
                typeName = "病假";
            } else if ("PERSONAL".equals(record.getType())) {
                typeName = "事假";
            } else if ("ADJUSTMENT".equals(record.getType())) {
                typeName = "调休";
            }
            String statusName = "APPROVED".equals(status) ? "已通过" : "已拒绝";
            createNotificationDirectly(
                record.getUserId(),
                "APPROVAL_RESULT",
                "审批结果：" + typeName + "申请",
                "您的" + typeName + "申请（" + record.getDays() + "天）" + statusName,
                leaveId,
                "LEAVE"
            );
        }
        
        return Result.success("审批完成");
    }
    
    public Result<List<LeaveRecord>> getMyLeaves(Long userId) {
        QueryWrapper<LeaveRecord> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userId);
        wrapper.orderByDesc("create_time");
        List<LeaveRecord> records = leaveMapper.selectList(wrapper);
        return Result.success(records);
    }
    
    public Result<List<LeaveRecord>> getPendingLeaves() {
        List<LeaveRecord> records = leaveMapper.selectPendingLeavesWithUserName();
        return Result.success(records);
    }
    
    // 假期统计（HR使用）
    public Result<Map<String, Object>> getLeaveStatistics() {
        Map<String, Object> statistics = new HashMap<>();
        
        // 统计各类型请假数量
        QueryWrapper<LeaveRecord> annualWrapper = new QueryWrapper<>();
        annualWrapper.eq("type", "ANNUAL");
        Long annualCount = leaveMapper.selectCount(annualWrapper);
        
        QueryWrapper<LeaveRecord> sickWrapper = new QueryWrapper<>();
        sickWrapper.eq("type", "SICK");
        Long sickCount = leaveMapper.selectCount(sickWrapper);
        
        QueryWrapper<LeaveRecord> personalWrapper = new QueryWrapper<>();
        personalWrapper.eq("type", "PERSONAL");
        Long personalCount = leaveMapper.selectCount(personalWrapper);
        
        QueryWrapper<LeaveRecord> adjustmentWrapper = new QueryWrapper<>();
        adjustmentWrapper.eq("type", "ADJUSTMENT");
        Long adjustmentCount = leaveMapper.selectCount(adjustmentWrapper);
        
        // 统计各状态数量
        QueryWrapper<LeaveRecord> pendingWrapper = new QueryWrapper<>();
        pendingWrapper.eq("status", "PENDING");
        Long pendingCount = leaveMapper.selectCount(pendingWrapper);
        
        QueryWrapper<LeaveRecord> approvedWrapper = new QueryWrapper<>();
        approvedWrapper.eq("status", "APPROVED");
        Long approvedCount = leaveMapper.selectCount(approvedWrapper);
        
        QueryWrapper<LeaveRecord> rejectedWrapper = new QueryWrapper<>();
        rejectedWrapper.eq("status", "REJECTED");
        Long rejectedCount = leaveMapper.selectCount(rejectedWrapper);
        
        statistics.put("annualCount", annualCount);
        statistics.put("sickCount", sickCount);
        statistics.put("personalCount", personalCount);
        statistics.put("adjustmentCount", adjustmentCount);
        statistics.put("pendingCount", pendingCount);
        statistics.put("approvedCount", approvedCount);
        statistics.put("rejectedCount", rejectedCount);
        statistics.put("totalCount", annualCount + sickCount + personalCount + adjustmentCount);
        
        return Result.success(statistics);
    }
    
    // 导出请假记录
    public void exportLeaveRecords(HttpServletResponse response, Long userId, String status) throws Exception {
        QueryWrapper<LeaveRecord> wrapper = new QueryWrapper<>();
        if (userId != null) {
            wrapper.eq("user_id", userId);
        }
        if (status != null && !status.isEmpty()) {
            wrapper.eq("status", status);
        }
        wrapper.orderByDesc("create_time");
        
        List<LeaveRecord> records = leaveMapper.selectList(wrapper);
        
        // 准备导出数据
        List<Map<String, Object>> exportData = new ArrayList<>();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat dateTimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        
        for (LeaveRecord record : records) {
            Map<String, Object> row = new HashMap<>();
            row.put("userName", record.getUserName() != null ? record.getUserName() : "员工" + record.getUserId());
            
            // 请假类型
            String typeName = "";
            if ("ANNUAL".equals(record.getType())) {
                typeName = "年假";
            } else if ("SICK".equals(record.getType())) {
                typeName = "病假";
            } else if ("PERSONAL".equals(record.getType())) {
                typeName = "事假";
            } else if ("ADJUSTMENT".equals(record.getType())) {
                typeName = "调休";
            }
            row.put("type", typeName);
            
            row.put("startDate", record.getStartDate() != null ? dateFormat.format(record.getStartDate()) : "");
            row.put("endDate", record.getEndDate() != null ? dateFormat.format(record.getEndDate()) : "");
            row.put("days", record.getDays() != null ? record.getDays() : 0);
            row.put("reason", record.getReason() != null ? record.getReason() : "");
            
            // 状态
            String statusName = "待审批";
            if ("APPROVED".equals(record.getStatus())) {
                statusName = "已通过";
            } else if ("REJECTED".equals(record.getStatus())) {
                statusName = "已拒绝";
            }
            row.put("status", statusName);
            row.put("createTime", record.getCreateTime() != null ? dateTimeFormat.format(record.getCreateTime()) : "");
            
            exportData.add(row);
        }
        
        // 表头
        String[] headers = {"员工姓名", "请假类型", "开始日期", "结束日期", "天数", "原因", "状态", "申请时间"};
        String[] fieldNames = {"userName", "type", "startDate", "endDate", "days", "reason", "status", "createTime"};
        
        // 导出Excel
        String fileName = "请假记录";
        if (status != null && !status.isEmpty()) {
            fileName += "_" + status;
        }
        com.ygswglxt.leave.util.ExcelExportUtil.exportExcel(
            response, 
            fileName, 
            headers, 
            exportData, 
            fieldNames
        );
    }
}

